home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 49 / Amiga Format CD49 (2000-01-17)(Future Publishing)(GB)(Track 1 of 3)[!][issue 2000-02].iso / -in_the_mag- / reader_requests / asciitable / sources / asciitable.c
C/C++ Source or Header  |  1999-11-29  |  12KB  |  431 lines

  1. /* ASCIITable **** Version 2.00, R.Florac, 14 novembre 1999
  2.  
  3.    This program is freeware, do what you want with it, but
  4.    please, send me your ideas for improvements or bug reports.
  5.  
  6.    Compiles with SASC :
  7.    sc link NOSTACKCHECK OPT STRINGMERGE ASCIITable.c */
  8.  
  9. #include <stdio.h>                /* for sprintf function */
  10. #include <string.h>
  11. #include <libraries/gtlayout.h>
  12. #include <libraries/iffparse.h>
  13. #include <libraries/locale.h>
  14. #include <libraries/commodities.h>
  15. #include <workbench/workbench.h>
  16. #include <workbench/startup.h>
  17.  
  18. #include <proto/exec.h>
  19. #include <proto/dos.h>
  20. #include <proto/commodities.h>
  21. #include <proto/icon.h>
  22. #include <proto/intuition.h>
  23. #include <proto/locale.h>
  24. #include <proto/iffparse.h>
  25. #include <proto/gtlayout_protos.h>        /* you need the gtlayout stuff */
  26. #include <pragmas/gtlayout_pragmas.h>
  27.  
  28.  
  29. #define ID_FTXT MAKE_ID('F','T','X','T')
  30. #define ID_CHRS MAKE_ID('C','H','R','S')
  31. #define EVT_HOTKEY 1
  32.  
  33. #define CATALOG_VERSION 1
  34.  
  35.  
  36. /* Gadgets ID (have to be greater than 255) */
  37. enum { STRING = 256, PAGE, CANCEL, ABOUT, QUIT, COPY, CLEAR };
  38.  
  39. struct Library * CxBase, * GTLayoutBase, * IFFParseBase, * IconBase, * LocaleBase;
  40. struct IntuitionBase * IntuitionBase;
  41. APTR catalogue;
  42. CxObj * commodity = 0, * filter, * sender, * traductor;
  43. struct LayoutHandle * handle = 0;
  44. unsigned char * hotkeys = "lcommand a";
  45. unsigned char lettres[(128-32)*2], texte[32] = "", window_title[40];
  46.  
  47. char info_title[] = "ASCIITable 2.00 (©) R.Florac 14/10/99";
  48.  
  49. /* Localization tables *******************************************************/
  50. enum { COMMODITY_TITLE, DESCRIPTION,
  51.     PAGE_ID, COPY_ID, DELETE_ID, INFO_ID, QUIT_ID,
  52.     OPERATION_FAILED, OPERATION_SUCCESS, CHARACTER, HEXA_STRING, DECIMAL_STRING
  53. };
  54.  
  55. char * strings[] = {
  56.     "ASCII table commodity", "Uses the clipboard.device",
  57.     "Page", "Copy", "Clear", "Info", "Quit", "Operation failed", "Operation succeeded",
  58.     "Char:", ", Hexa:", ", Decimal:"
  59. };
  60.  
  61.  
  62. /* Commodity structure *******************************************************/
  63. struct NewBroker newbroker = {
  64.     NB_VERSION,     /* nb_Version - Version of the NewBroker structure */
  65.     "ASCIITable",   /* nb_Name - Name Commodities uses to identify this commodity */
  66.     0,            /* nb_Title - Title of commodity that appears in CXExchange */
  67.     0,            /* nb_Descr - Description of the commodity */
  68.     NBU_UNIQUE | NBU_NOTIFY,        /* nb_Unique - Tells CX not to launch another commodity with same name */
  69.     COF_SHOW_HIDE,  /* nb_Flags - Tells CX if this commodity has a window */
  70.     0,            /* nb_Pri - This commodity's priority */
  71.     0,            /* nb_Port - MsgPort CX talks to */
  72.     0            /* nb_ReservedChannel - reserved for later use */
  73. };
  74.  
  75.  
  76. void __regargs init_textes_gadgets (unsigned char first_letter)
  77. {   long i = 0, j;
  78.     for (j = 32;  j < 128;  j++)
  79.     {    lettres[i++] = first_letter++;    lettres[i++]=0; }
  80. }
  81.  
  82. void __regargs gadget_letter (char * label, long id)
  83. {
  84.     LT_New (handle, LA_Type, BUTTON_KIND, LA_NoKey, TRUE, LA_LabelText, label, LA_ID, id, TAG_DONE);
  85. }
  86.  
  87. void __regargs groupe_horizontal (char * letters, long line)
  88. {   long i;
  89.     LT_New (handle, LA_Type, HORIZONTAL_KIND, TAG_DONE);
  90.     for (i = 0;  i < 16;  i++)
  91.     gadget_letter (&letters[2*i], line+i);
  92.     LT_EndGroup (handle);
  93. }
  94.  
  95. unsigned char * __regargs GetString (long i)
  96. {   unsigned char * def = strings[i];
  97.     return (catalogue ? GetCatalogStr (catalogue, i, def) : def);
  98. }
  99.  
  100. __saveds __asm unsigned char * LocaleHookFunc (register __a0 struct Hook * UnusedHook, register __a2 APTR Unused, register __a1 long ID)
  101. {
  102.     return GetString(ID);
  103. }
  104.  
  105. struct Hook LocaleHook = { 0, 0, (HOOKFUNC) LocaleHookFunc, 0, 0 };
  106.  
  107. void __regargs set_string (char * t)
  108. {
  109.     LT_SetAttributes (handle, STRING, GTST_String, t, TAG_END);
  110. }
  111.  
  112. void close_window (void)
  113. {
  114.     LT_DeleteHandle (handle);
  115.     handle = 0;
  116. }
  117.  
  118. void __regargs set_title (char * t)
  119. {
  120.     SetWindowTitles (handle->Window, t, (char *) -1);
  121. }
  122.  
  123. void __regargs open_window (void)
  124. {
  125.     long i;
  126.  
  127.     handle = LT_CreateHandleTags (0, LAHN_LocaleHook, &LocaleHook,TAG_DONE);
  128.     if (handle)
  129.     {    LT_New (handle, LA_Type, VERTICAL_KIND, TAG_DONE);
  130.     {   for (i = 0;  i < 6;  i++)
  131.         groupe_horizontal (lettres + i * 32, 16 * i);
  132.         LT_New (handle, LA_Type, XBAR_KIND, TAG_DONE);
  133.         LT_New (handle, LA_Type, STRING_KIND, GTST_String, texte, GTST_MaxChars, 30, LA_ID, STRING, TAG_DONE);
  134.         LT_New (handle, LA_Type, HORIZONTAL_KIND, LAGR_SameSize, TRUE, LAGR_Spread, TRUE, TAG_DONE);
  135.         {
  136.         LT_New (handle, LA_Type, BUTTON_KIND, LA_LabelID, PAGE_ID, LA_ID, PAGE, TAG_DONE);
  137.         LT_New (handle, LA_Type, BUTTON_KIND, LA_LabelID, COPY_ID, LA_ID, COPY, TAG_DONE);
  138.         LT_New (handle, LA_Type, BUTTON_KIND, LA_LabelID, DELETE_ID, LA_ID, CLEAR, TAG_DONE);
  139.         LT_New (handle, LA_Type, BUTTON_KIND, LA_LabelID, INFO_ID, LA_ID, ABOUT, TAG_DONE);
  140.         LT_New (handle, LA_Type, BUTTON_KIND, LA_LabelID, QUIT_ID, LA_ID, QUIT, TAG_DONE);
  141.         LT_EndGroup (handle);
  142.         }
  143.         LT_EndGroup (handle);
  144.     }
  145.     if (! LT_Build (handle,
  146.         LAWN_Title,     info_title,
  147.         LAWN_BelowMouse,    TRUE,
  148.         WA_DepthGadget,    TRUE,
  149.         WA_DragBar,     TRUE,
  150.         WA_Activate,    TRUE,
  151.         WA_CloseGadget,    TRUE,
  152.         WA_RMBTrap,     TRUE,
  153.         LAWN_IDCMP,     IDCMP_CLOSEWINDOW | CHECKBOXIDCMP,
  154.     TAG_DONE))
  155.         close_window ();
  156.     }
  157. }
  158.  
  159. void __regargs copy (char * t)
  160. {   long error = 1;
  161.     struct IFFHandle * iff;
  162.  
  163.     if (IFFParseBase = OpenLibrary ("iffparse.library", 0L))
  164.     {    if (iff = AllocIFF ())
  165.     {   if (iff->iff_Stream = (ULONG) OpenClipboard (0))
  166.         {    InitIFFasClip (iff);
  167.         if (! OpenIFF (iff, IFFF_WRITE))
  168.         {   if (! PushChunk (iff, ID_FTXT, ID_FORM, IFFSIZE_UNKNOWN))
  169.             {    if (! PushChunk (iff, 0, ID_CHRS, IFFSIZE_UNKNOWN))
  170.             {   error = strlen (t);
  171.                 if (WriteChunkBytes (iff, t, error) == error)
  172.                 error = 0;
  173.             }
  174.             if (error == 0) error = PopChunk (iff);
  175.             }
  176.             if (error == 0) error = PopChunk (iff);
  177.             CloseIFF(iff);
  178.         }
  179.         CloseClipboard ((struct ClipboardHandle *) iff->iff_Stream);
  180.         }
  181.         FreeIFF (iff);
  182.     }
  183.     CloseLibrary (IFFParseBase);
  184.     }
  185.     if (error)
  186.     set_title (GetString(OPERATION_FAILED));
  187.     else
  188.     set_title (GetString(OPERATION_SUCCESS));
  189. }
  190.  
  191. BOOL open_all (void)
  192. {   if (LocaleBase = OpenLibrary ("locale.library",38))     /* Perhaps some library versions to change... */
  193.     catalogue = OpenCatalog (NULL, "ASCIITable.catalog", OC_Version, CATALOG_VERSION, TAG_DONE);
  194.     if (IntuitionBase = (struct IntuitionBase *) OpenLibrary ("intuition.library", 37))
  195.     if (GTLayoutBase = OpenLibrary ("gtlayout.library", 39L))
  196.         if (CxBase = OpenLibrary ("commodities.library", 37) )
  197.         {    newbroker.nb_Title = GetString (COMMODITY_TITLE);
  198.         newbroker.nb_Descr = GetString (DESCRIPTION);
  199.         return 1;
  200.         }
  201.     return 0;
  202. }
  203.  
  204. void close_all (void)
  205. {
  206.     if (catalogue)
  207.     CloseCatalog (catalogue);
  208.     if (LocaleBase)
  209.     CloseLibrary (LocaleBase);
  210.     if (commodity)
  211.     DeleteCxObjAll (commodity);
  212.     if (newbroker.nb_Port)
  213.     {    struct Message * message;
  214.     while (message = GetMsg (newbroker.nb_Port))
  215.         ReplyMsg (message);
  216.     DeletePort (newbroker.nb_Port);
  217.     }
  218.     if (CxBase)
  219.     CloseLibrary (CxBase);
  220.     if (GTLayoutBase)
  221.     CloseLibrary (GTLayoutBase);
  222.     if (IntuitionBase)
  223.     CloseLibrary ((struct Library *) IntuitionBase);
  224. }
  225.  
  226. long __regargs handle_commodity (CxMsg * message)
  227. {   ULONG type_message = CxMsgType (message), identificateur = CxMsgID (message);
  228.     long end = 0;
  229.     ReplyMsg ((struct Message *) message);
  230.     switch (type_message)
  231.     {    case CXM_IEVENT:
  232.         if (identificateur == EVT_HOTKEY)        /* Combinaison touches d'appel */
  233.         if (handle)
  234.             close_window ();
  235.         else
  236.             open_window ();
  237.         break;
  238.     case CXM_COMMAND:
  239.         switch (identificateur)
  240.         {    case CXCMD_DISABLE:        /* Désactivation de la commodité */
  241.             ActivateCxObj (commodity, 0);  break;
  242.         case CXCMD_ENABLE:        /* Activation de la commodité */
  243.             ActivateCxObj (commodity, 1);  break;
  244.         case CXCMD_DISAPPEAR:
  245.             close_window ();
  246.             break;
  247.         case CXCMD_KILL:
  248.             end = 1;        break;
  249.         case CXCMD_UNIQUE:        /* On a tenté de relancer... */
  250.             if (handle)
  251.             {    end = 1;    break;  }
  252.         case CXCMD_APPEAR:
  253.             if (handle)
  254.             WindowToFront (handle->Window);
  255.             else
  256.             open_window ();
  257.         }
  258.     }
  259.     return end;
  260. }
  261.  
  262. unsigned char * addspace (unsigned char * t)
  263. {   long l =strlen (t);
  264.     t += l;
  265.     *t = ' ';
  266.     t++;
  267.     *t = 0;
  268.     return t;
  269. }
  270.  
  271. long handle_window (void)
  272. {
  273.     struct IntuiMessage *message;
  274.     struct Gadget * gad;
  275.     long end = 0;
  276.     static long page = 1, rang = 0;
  277.     ULONG classe;
  278.     unsigned char * lettre, * t;
  279.  
  280.     while (message = LT_GetIMsg (handle))
  281.     {    classe = message->Class;
  282.     gad = (struct Gadget *) message->IAddress;
  283.     LT_ReplyIMsg (message);
  284.     switch (classe)
  285.     {   case IDCMP_CLOSEWINDOW:
  286.         close_window ();    return 0;
  287.         case IDCMP_GADGETUP:
  288.         /* Each ASCII char gadget has an ID corresponding to its ASCII code */
  289.         if (gad->GadgetID < 256)
  290.         {   lettre = lettres + 2 * gad->GadgetID;
  291.             /* and then, better than sprintf but a bit harder... (2k bytes saved) */
  292.             strcpy (window_title, GetString(CHARACTER));
  293.             t = addspace (window_title);
  294.             * t= * lettre;
  295.             strcpy (++t, GetString (HEXA_STRING));
  296.             t = addspace (t);
  297.             stcl_h (t, * lettre);
  298.             strcat (t, GetString(DECIMAL_STRING));
  299.             t = addspace (t);
  300.             stcl_d (t, * lettre);
  301.             set_title (window_title);
  302.             if (rang < 30)
  303.             {    texte[rang++] = * lettre;
  304.             texte[rang] = 0;
  305.             set_string (texte);
  306.             }
  307.         }
  308.         else
  309.         {   switch (gad->GadgetID)
  310.             {    case PAGE:
  311.                 page ^= 1;
  312.                 init_textes_gadgets (page ? 160 : ' ');
  313.                 RefreshGList (handle->Window->FirstGadget, handle->Window, 0, -1);
  314.                 break;
  315.             case COPY:
  316.                 if (rang)           /* NEVER copy a null string ! */
  317.                 copy (texte);
  318.                 break;
  319.             case CLEAR:
  320.                 texte[rang = 0] = 0;
  321.                 set_string (texte);
  322.             case ABOUT:
  323.                 set_title (info_title);
  324.                 break;
  325.             case QUIT:
  326.                 end = 1;    break;
  327.             case STRING:
  328.                 lettre = (unsigned char *) LT_GetAttributes (handle, STRING, TAG_DONE);
  329.                 strcpy (texte, lettre);
  330.                 rang = strlen(texte);
  331.                 break;
  332.             }
  333.         }
  334.         break;
  335.     }
  336.     }
  337.     if (end)
  338.     close_window ();
  339.     return end;
  340. }
  341.  
  342. void handle_events (void)
  343. {
  344.     long end = 0;
  345.     ULONG signal_reçu;
  346.     struct Message * message;
  347.  
  348.     while (! end)
  349.     {    ULONG signaux = 0;
  350.     if (handle)
  351.         signaux = 1 << handle->Window->UserPort->mp_SigBit;
  352.     signaux |= SIGBREAKF_CTRL_C | 1L << newbroker.nb_Port->mp_SigBit;
  353.     signal_reçu = Wait (signaux);
  354.     if (handle)
  355.         end = handle_window ();
  356.     if (signal_reçu & SIGBREAKF_CTRL_C)
  357.         end = 1;
  358.     if (signal_reçu & 1L << newbroker.nb_Port->mp_SigBit)
  359.         while (message = GetMsg (newbroker.nb_Port))
  360.         end |= handle_commodity ((CxMsg *) message);
  361.     }
  362.     if (handle);
  363.     close_window ();
  364. }
  365.  
  366. long init_commodity (void)
  367. {   if (newbroker.nb_Port = CreateMsgPort())
  368.     {    newbroker.nb_Pri = 0;
  369.     if (commodity = CxBroker (&newbroker, 0))
  370.     {   if (filter = CxFilter (hotkeys))
  371.         {    AttachCxObj (commodity, filter);
  372.         if (sender = CxSender (newbroker.nb_Port, EVT_HOTKEY) )
  373.         {   AttachCxObj (filter, sender);
  374.             if (traductor = CxTranslate (0))
  375.             {    AttachCxObj (filter, traductor);
  376.             if (! CxObjError (filter))
  377.             {   ActivateCxObj (commodity, 1);
  378.                 return 1;
  379.             }
  380.             }
  381.         }
  382.         }
  383.     }
  384.     }
  385.     return 0;
  386. }
  387.  
  388. void main (long argc, char ** argv)
  389. {
  390.     BOOL open = 1;
  391.  
  392.     if (open_all ())
  393.     {    if (argc == 0)
  394.     {   struct WBStartup * WBenchMsg;
  395.         struct WBArg * wbarg;
  396.         struct DiskObject * dobj;
  397.         char ** toolarray, * s;
  398.         BPTR olddir = -1;
  399.         if (IconBase = OpenLibrary ("icon.library", 33))
  400.         {    WBenchMsg = (struct WBStartup *) argv;
  401.         wbarg = WBenchMsg->sm_ArgList;
  402.         if ((wbarg->wa_Lock)  &&  (*wbarg->wa_Name))
  403.             olddir = CurrentDir (wbarg->wa_Lock);
  404.         if ((*wbarg->wa_Name)  &&  (dobj = GetDiskObject (wbarg->wa_Name)))
  405.         {   toolarray = (char **) dobj->do_ToolTypes;
  406.             if (s = (char *) FindToolType (toolarray, "CX_POPKEY"))
  407.             hotkeys = s;
  408.             if (s = (char *) FindToolType (toolarray, "CX_POPUP"))
  409.             if (MatchToolValue (s, "NO"))
  410.                 open = 0;
  411.             FreeDiskObject (dobj);
  412.         }
  413.         if (olddir != -1)
  414.             CurrentDir (olddir);
  415.         CloseLibrary (IconBase);
  416.         }
  417.     }
  418.     if (argc > 1)
  419.         if (stricmp (argv[1], "NOWIN") == 0)
  420.         open = 0;
  421.     init_textes_gadgets (160);
  422.     if (init_commodity ())
  423.     {
  424.         if (open)
  425.         open_window ();
  426.         handle_events ();
  427.     }
  428.     }
  429.     close_all ();
  430. }
  431.